bpmn.Bpmn = zk.$extends(zul.Widget, {

	_readonly:false,
    _value:null,
    _bpmnModeler:null,
    _currentElement:null,
    _count: 0,
    _imgJson: {},
    _rootSign:false,


    /*$init: function () {
        this.$supers('$init', arguments);
    },*/

	$define: {
        value: function() {
			if(this.desktop) {
                this.drawDiagram_();
			}
		},
        readonly: function() {

        }
	},

	bind_: function () {
		this.$supers(bpmn.Bpmn,'bind_', arguments);
		this.init_();
	},

    unbind_: function () {
        this.$supers(bpmn.Bpmn,'unbind_', arguments);
    },


    init_:function () {
        if (this._value==null){
            //基本样式
            this._value="<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                "<definitions xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:omgdc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" targetNamespace=\"\" xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd\">" +
                "  <collaboration id=\"sid-c0e745ff-361e-4afb-8c8d-2a1fc32b1424\">" +
                "    <participant id=\"Participant_0far81h\" name=\"Default\" processRef=\"Process_144dsjr\" />" +
                "  </collaboration>" +
                "  <process id=\"Process_144dsjr\" name=\"Default\" isExecutable=\"true\" />" +
                "  <bpmndi:BPMNDiagram id=\"sid-74620812-92c4-44e5-949c-aa47393d3830\">" +
                "    <bpmndi:BPMNPlane id=\"sid-cdcae759-2af7-4a6d-bd02-53f3352a731d\" bpmnElement=\"sid-c0e745ff-361e-4afb-8c8d-2a1fc32b1424\">" +
                "      <bpmndi:BPMNShape id=\"Participant_0far81h_di\" bpmnElement=\"Participant_0far81h\" isHorizontal=\"true\">" +
                "        <omgdc:Bounds x=\"180\" y=\"80\" width=\"740\" height=\"400\" />" +
                "      </bpmndi:BPMNShape>" +
                "    </bpmndi:BPMNPlane>" +
                "    <bpmndi:BPMNLabelStyle id=\"sid-e0502d32-f8d1-41cf-9c4a-cbb49fecf581\">" +
                "      <omgdc:Font name=\"Arial\" size=\"11\" isBold=\"false\" isItalic=\"false\" isUnderline=\"false\" isStrikeThrough=\"false\" />" +
                "    </bpmndi:BPMNLabelStyle>" +
                "    <bpmndi:BPMNLabelStyle id=\"sid-84cb49fd-2f7c-44fb-8950-83c3fa153d3b\">" +
                "      <omgdc:Font name=\"Arial\" size=\"12\" isBold=\"false\" isItalic=\"false\" isUnderline=\"false\" isStrikeThrough=\"false\" />" +
                "    </bpmndi:BPMNLabelStyle>" +
                "  </bpmndi:BPMNDiagram>" +
                "</definitions>";
        }

        if(this._readonly) {
            this.bpmnModeler = new BpmnJS({
                container: '#' + this.uuid + '-canvas'
            });
        }else{
            this.bpmnModeler = new BpmnJS({
                container: '#' + this.uuid + '-canvas',
                //工具栏
                keyboard: {
                    bindTo: window
                },
                //汉化方法
                additionalModules: [
                    {
                        translate: ['value',  function customTranslate(template, replacements) {
                            replacements = replacements || {};
                            // Translate
                            template = translations[template] || template;
                            // Replace
                            return template.replace(/{([^}]+)}/g, function(_, key) {
                                /*var str = replacements[key];
                                if (translations[replacements[key]] != null && translations[replacements[key]] !== 'undefined') {
                                    str = translations[replacements[key]]
                                }*/
                                return replacements[key] || '{' + key + '}';
                            });
                        }]
                    }
                ]
            });
        }
        var self = this;
        const eventBus = this.bpmnModeler.get('eventBus');
        const eventTypes = ['element.click', 'element.hover','element.changed','shape.remove'];
        //节点鼠标点击和划过监听
        eventTypes.forEach( function (eventType) {
            eventBus.on(eventType, function (e) {
                const element = e.element;
                if (!element.parent) return;
                if (!e || element.type === 'bpmn:Process') {
                    return false;
                } else {
                    if (eventType === 'element.click') {
                        // 节点点击后想要做的处理
                    } else if (eventType === 'element.hover') {
                        // 鼠标滑过节点后想要做的处理
                    } else if (eventType === 'element.changed'){
                        // 节点属性变化做的处理
                        self.changePanelName_();
                    }else if (eventType === 'shape.remove'){
                        // 节点删除做的处理
                        self.currentElement=null;
                        self.changePanelContent_();
                    }
                }
            });
        });
        //节点选择变化监听,逻辑与上面不一致单独添加监听
        this.bpmnModeler.on('selection.changed',function (e) {
            const element = e.newSelection[0];
            if (element){
                self.currentElement = element;
                self.openPanel_(element.type);
            }
        });
        this.drawDiagram_();
    },

    //渲染图形
    drawDiagram_: function () {
        if (this.bpmnModeler) {
            try {
                this.bpmnModeler.importXML(this._value);
                this.openPanel_();
                this.togglePanelDiv_(true);
            } catch (err) {
                console.error('could not import BPMN 2.0 diagram', err);
            }
        }
    },

    //打开面板，控制面板展示的属性
    openPanel_: function (type) {
        this.cleanPropertyDiv_();
        this.togglePanelDiv_(false);
        if(type == "bpmn:Participant" ){
            this._rootSign = true;
            $("#" +this.uuid+"-processDiv").css("display","block");
            $("#" +this.uuid+"-taskDiv").css("display","none");
            this.changePanelContent_(this._rootSign);
        }else{
            this._rootSign = false;
            $("#" +this.uuid+"-processDiv").css("display","none");
            $("#" +this.uuid+"-taskDiv").css("display","block");
            this.changePanelContent_(this._rootSign);
        }
    },

    //节点处名称改变时改变面板名称属性
    changePanelName_:function () {
        if (this.currentElement){
            const property = this.currentElement.businessObject;
            $("#" + this.uuid + "-name").attr('value', property.name);
        }
    },

    //改变控制面板属性
    changePanelContent_:function (isRoot) {
	    if(this.currentElement) {
            console.log(this.currentElement);
            this._count = 0;
            $("#" + this.uuid + "-id").removeAttr("disabled");
            $("#" + this.uuid + "-name").removeAttr("disabled");
            $("#" +this.uuid+"-executable").removeAttr("disabled");
            $("#" + this.uuid + "-version").removeAttr("disabled");
            $("#" + this.uuid + "-task").removeAttr("disabled");
            $("#" + this.uuid + "-work").removeAttr("disabled");
            $("#" +this.uuid+"-processId").removeAttr("disabled");
            $("#" +this.uuid+"-processName").removeAttr("disabled");
            $("#" +this.uuid+"-documentation").removeAttr("disabled");
            $("#" +this.uuid+"-asynchronous-before").removeAttr("disabled");
            $("#" +this.uuid+"-asynchronous-after").removeAttr("disabled");
            $("#" +this.uuid+"-addPropertyButton").removeAttr("disabled");
            if(this.currentElement.businessObject.$type &&
                this.currentElement.businessObject.$type !== "") {
                var type = this.currentElement.businessObject.$type;
                type = type.substr(type.indexOf(":")+1,type.length);
                type = translations[type] || type;
                $("#" + this.uuid + "-label").text(type);
            }else{
                $("#" + this.uuid + "-label").text("Element");
            }
            if(this.currentElement.businessObject.id &&
                this.currentElement.businessObject.id !== "") {
                $("#" + this.uuid + "-id").val(this.currentElement.businessObject.id);
            }else{
                $("#" + this.uuid + "-id").val("");
            }
            if(this.currentElement.businessObject.name &&
                this.currentElement.businessObject.name !== "") {
                $("#" + this.uuid + "-name").val(this.currentElement.businessObject.name);
            }else{
                $("#" + this.uuid + "-name").val("");
            }

            if(isRoot){
                //根节点基本属性
                if(this.currentElement.businessObject.processRef &&
                    this.currentElement.businessObject.processRef.isExecutable
                    && this.currentElement.businessObject.processRef.isExecutable === true){
                    $("#" +this.uuid+"-executable").attr("checked","checked");
                }else{
                    $("#" +this.uuid+"-executable").removeAttr('checked');
                }
                if(this.currentElement.businessObject.processRef &&
                    this.currentElement.businessObject.processRef.$attrs &&
                    this.currentElement.businessObject.processRef.$attrs.taskPriority !== ""){
                    $("#" + this.uuid+"-task").val(this.currentElement.businessObject.processRef.$attrs.taskPriority);
                }else{
                    $("#" + this.uuid+"-task").val("");
                }
                if(this.currentElement.businessObject.processRef &&
                    this.currentElement.businessObject.processRef.$attrs &&
                    this.currentElement.businessObject.processRef.$attrs.jobPriority !== ""){
                    $("#" +this.uuid+"-work").val(this.currentElement.businessObject.processRef.$attrs.jobPriority);
                }else{
                    $("#" +this.uuid+"-work").val("");
                }
                if(this.currentElement.businessObject.processRef &&
                    this.currentElement.businessObject.processRef.$attrs &&
                    this.currentElement.businessObject.processRef.$attrs.versionTag !== ""){
                    $("#" +this.uuid+"-version").val(this.currentElement.businessObject.processRef.$attrs.versionTag);
                }else{
                    $("#" +this.uuid+"-version").val("");
                }
                if(this.currentElement.businessObject.processRef &&
                    this.currentElement.businessObject.processRef.id
                    && this.currentElement.businessObject.processRef.id !== ""){
                    $("#" +this.uuid+"-processId").val(this.currentElement.businessObject.processRef.id);
                }else{
                    $("#" +this.uuid+"-processId").val("");
                }
                if(this.currentElement.businessObject.processRef &&
                    this.currentElement.businessObject.processRef.name &&
                    this.currentElement.businessObject.processRef.name !== ""){
                    $("#" +this.uuid+"-processName").val(this.currentElement.businessObject.processRef.name);
                }else{
                    $("#" +this.uuid+"-processName").val("");
                }
                //根节点拓展属性
                if(this.currentElement.businessObject.processRef.$attrs &&
                    JSON.stringify(this.currentElement.businessObject.processRef.$attrs) != '{}'){
                    var obj = this.currentElement.businessObject.processRef.$attrs;
                    this._count = obj.length;
                    for(var key in obj) {
                        this.addPropertyDiv_(key,obj[key]);
                    }
                }

            }else{
                //非根节点基本属性
                if(this.currentElement.businessObject.documentation &&
                    this.currentElement.businessObject.documentation !== "") {
                    $("#" +this.uuid+"-documentation").val(this.currentElement.businessObject.documentation);
                }else{
                    $("#" +this.uuid+"-documentation").val("");
                }
                if(this.currentElement.businessObject.asyncBefore &&
                    this.currentElement.businessObject.asyncBefore  === true) {
                    $("#" +this.uuid+"-asynchronous-before").attr("checked","checked");
                }else{
                    $("#" +this.uuid+"-asynchronous-before").removeAttr('checked');
                }
                if(this.currentElement.businessObject.asyncAfter &&
                    this.currentElement.businessObject.asyncAfter  === true) {
                    $("#" +this.uuid+"-asynchronous-after").attr("checked","checked");
                }else{
                    $("#" +this.uuid+"-asynchronous-after").removeAttr('checked');
                }
                //拓展属性展示
                if(this.currentElement.businessObject.$attrs &&
                    JSON.stringify(this.currentElement.businessObject.$attrs) != '{}'){
                    this.cleanPropertyDiv_();
                    var obj = this.currentElement.businessObject.$attrs;
                    this._count = obj.length;
                    for(var key in obj) {
                        this.addPropertyDiv_(key,obj[key]);
                    }
                }
            }

        }else{
            $("#" + this.uuid + "-label").text("Element");
            $("#" + this.uuid + "-id").val("");
            $("#" + this.uuid + "-name").val("");
            $("#" + this.uuid + "-version").val("");
            $("#" + this.uuid + "-task").val("");
            $("#" + this.uuid + "-work").val("");
            $("#" +this.uuid+"-processId").val("");
            $("#" +this.uuid+"-processName").val("");
            $("#" +this.uuid+"-documentation").val("");
            $("#" +this.uuid+"-executable").removeAttr('checked');
            $("#" +this.uuid+"-asynchronous-before").removeAttr('checked');
            $("#" +this.uuid+"-asynchronous-after").removeAttr('checked');
            $("#" + this.uuid + "-id").attr("disabled","disabled");
            $("#" + this.uuid + "-name").attr("disabled","disabled");
            $("#" +this.uuid+"-executable").attr("disabled","disabled");
            $("#" + this.uuid + "-version").attr("disabled","disabled");
            $("#" + this.uuid + "-task").attr("disabled","disabled");
            $("#" + this.uuid + "-work").attr("disabled","disabled");
            $("#" +this.uuid+"-processId").attr("disabled","disabled");
            $("#" +this.uuid+"-processName").attr("disabled","disabled");
            $("#" +this.uuid+"-documentation").attr("disabled","disabled");
            $("#" +this.uuid+"-asynchronous-before").attr("disabled","disabled");
            $("#" +this.uuid+"-asynchronous-after").attr("disabled","disabled");
            $("#" +this.uuid+"-addPropertyButton").attr("disabled","disabled");

        }
    },

    //改变节点属性
    changeProperty_:function (tag) {
        if (this.currentElement) {
            if (tag.id === this.uuid + '-id') {
                this.changePropertyDetail_(this.currentElement, { id : tag.value });
            } else if (tag.id === this.uuid + '-name') {
                //更新节点label内容
                const modeling = this.bpmnModeler.get('modeling');
                modeling.updateLabel(this.currentElement, tag.value);
                this.changePropertyDetail_(this.currentElement, { name : tag.value },false);
            } else if(tag.id === this.uuid + '-user'){
                this.changePropertyDetail_(this.currentElement, { user : tag.value },false);
            } else if(tag.id === this.uuid + '-role'){
                this.changePropertyDetail_(this.currentElement, { role : tag.value },false);
            } else if(tag.id === this.uuid + '-group'){
                this.changePropertyDetail_(this.currentElement, { group : tag.value },false);
            } else if(tag.id === this.uuid + '-executable'){
                this.changePropertyDetail_(this.currentElement, { isExecutable : tag.checked },true);
            } else if(tag.id === this.uuid + '-version'){
                this.changePropertyDetail_(this.currentElement, { versionTag : tag.value },true);
            } else if(tag.id === this.uuid + '-task'){
                this.changePropertyDetail_(this.currentElement, { taskPriority : tag.value },true);
            } else if(tag.id === this.uuid + '-work'){
                this.changePropertyDetail_(this.currentElement, { jobPriority : tag.value },true);
            } else if(tag.id === this.uuid + '-processId'){
                this.changePropertyDetail_(this.currentElement, { id : tag.value },true);
            } else if(tag.id === this.uuid + '-processName'){
                this.changePropertyDetail_(this.currentElement, { name : tag.value },true);
            } else if(tag.id === this.uuid+"-documentation"){
                this.changePropertyDetail_(this.currentElement, { documentation : tag.value },false);
            } else if(tag.id === this.uuid+"-asynchronous-before"){
                this.changePropertyDetail_(this.currentElement, { asyncBefore : tag.checked },false);
            } else if(tag.id === this.uuid+"-asynchronous-after"){
                this.changePropertyDetail_(this.currentElement, { asyncAfter : tag.checked },false);
            }
        }
    },

    //修改属性通用方法
    changePropertyDetail_:function (element,value,isRoot) {
        if (this.bpmnModeler) {
            const modeling = this.bpmnModeler.get('modeling');
            if (isRoot) {
                modeling.updateModdleProperties(element,element.businessObject.processRef,value);
            }else {
                modeling.updateProperties(element, value);
            }
        }
    },


    //生成XML
    save_:function () {
        if (this.bpmnModeler) {
            try {
                var self = this;
                var result = this.bpmnModeler.saveXML({format: true});
                result.then(function(res){
                    self.fire('onSave',{data:res.xml});
                });
            } catch (err) {
                console.error('could not save BPMN 2.0 diagram', err);
            }
        }
    },

    //tab切换修改样式
    tabChange_:function (tag) {
        $('.j2pass-bpmn-li a').removeClass("j2pass-bpmn-a-select");
        $('.j2pass-bpmn-li a').addClass("j2pass-bpmn-a-unselect");
        $(tag).children().removeClass("j2pass-bpmn-a-unselect");
        $(tag).children().addClass("j2pass-bpmn-a-select");
        if(tag.id == this.uuid + '-general-li'){
            $("#" +this.uuid+"-generalDiv").css("display","block");
            $("#" +this.uuid+"-propertyDiv").css("display","none");
        } else if(tag.id == this.uuid + '-property-li'){
            $("#" +this.uuid+"-generalDiv").css("display","none");
            $("#" +this.uuid+"-propertyDiv").css("display","block");
        }
    },

    //添加拓展属性div
    addPropertyDiv_:function (key,value) {
        $('#'+this.uuid+'-propertyContentDiv').append(
            '<div id="'+this.uuid+'-addPropertyDiv'+this._count+'" style="margin-top: 10px;">' +
            '<div class="j2pass-bpmn-panel-add-property-div">' +
            '<label class="j2pass-bpmn-panel-add-property-label">Name</label>' +
            '<label class="j2pass-bpmn-panel-add-property-label">Value</label>' +
            '</div>' +
            '<div class="j2pass-bpmn-panel-add-property-div">' +
            '<input class="j2pass-bpmn-panel-add-property-input" data-count="'+this._count+'" id="'+this.uuid+'-addPropertyKey'+this._count+'" style="margin-right:14px;" type="text" name="name" onChange="zk.$('+this.uuid+').addPropertyChangeKey_(this)" value="'+key+'">' +
            '<input class="j2pass-bpmn-panel-add-property-input" data-count="'+this._count+'" id="'+this.uuid+'-addPropertyValue'+this._count+'" type="text" name="value"  onChange="zk.$('+this.uuid+').addPropertyChangeValue_(this)" value="'+value+'">' +
            '<button class="j2pass-bpmn-panel-property-button" data-count="'+this._count+'" onclick="zk.$('+this.uuid+').deletePropertyDiv_(this)">' +
            '<span class="j2pass-bpmn-panel-property-span">X</span>' +
            '</button>' +
            '</div>' +
            '</div>');
        if(!value || value == ""){
            $('#'+this.uuid+'-addPropertyValue'+this._count).attr("disabled","disabled");
        }
        this._count = $('#'+this.uuid+'-propertyContentDiv').children().length;
    },

    //清除所有拓展属性div
    cleanPropertyDiv_:function () {
        $('#'+this.uuid+'-propertyContentDiv').empty();
    },

    //拓展属性key修改
    addPropertyChangeKey_:function (tag) {
        if(tag.value && tag.value != ""){
            $('#'+this.uuid+'-addPropertyValue'+tag.dataset.count).removeAttr("disabled");
        }else{
            $('#'+this.uuid+'-addPropertyValue'+tag.dataset.count).attr("disabled","disabled");
        }
    },

    //拓展属性value修改
    addPropertyChangeValue_:function (tag) {
        if(tag.value && tag.value != ""){
            var key = $('#' + this.uuid + '-addPropertyKey' + tag.dataset.count).val();
            var value = tag.value;
            var obj = {};
            obj[key] = value;
            this.changePropertyDetail_(this.currentElement, obj, this._rootSign);
        }
    },

    //删除拓展属性div
    deletePropertyDiv_:function (tag) {
        var key = $('#' + this.uuid + '-addPropertyKey' + tag.dataset.count).val();
        if(this._rootSign){
            var obj = this.currentElement.businessObject.processRef.$attrs;
            delete obj[key];
        }else{
            var obj = this.currentElement.businessObject.$attrs;
            delete obj[key];
        }
        $(tag.parentElement.parentElement).remove();
        this._count = $('#'+this.uuid+'-propertyContentDiv').children().length;
    },

    //隐藏属性面板div
    togglePanelDiv_:function (hiddenSign) {
        if (hiddenSign && $('#' + this.uuid + '-Panel').width() != 0 ) {
            $('#' + this.uuid + '-Panel').css('width', '0px');
        }else{
            $('#' + this.uuid + '-Panel').css('width', '280px');
        }
    },

});